FAQ about the TMultLang component in Delphi 1.x and 2.x Q. I am primarly using Delphi 2.0 as my development environment, but I would also like to compile my project in Delphi 1.0 with the TMultLang package. Do I have to make two copies of the project files ? A Wether you are working with Delphi 1 or 2 it will be full compability between them. The *.LAN files as well as the internal storage of the TMultLang component are using the same structure, you can therefore use the same code (project files) under each environment. You should be aware that the only difference is that under Delphi 2, huge strings are supported, those will be chopped off at the length of 255 bytes in Delphi 1. Q. I would like to send my translator a textfile which I later would like to use in my application, because the translator does not have Delphi. Can this be done with the TMultLang package ? A. Yes, you can export and import translations from and to textfiles. However, you will get one textfile per form. A more elegant solution is to compile your application to your EXE file. Give this EXE file to your translator, he would then be able to translate your application at run-time, without source and without Delphi. You can do this by calling the Edit method of the TMultLang component at run-time if you have specified an external (*.LAN) translation file (the LanguageFile property). Q. When using the TMultLang component with MDI windows, it seems that the childrens merged menus will only be translated to the previous selected language. But this does only seem to happen when I switch language from the Main Form, but not from the children. Is something wrong ? A. The reason is that Delphi does not update the Main MDI Form menu that is merged from the children directly. This can be worked around by instruct the TMultLang component to translate the children menus before the Main MDI form menu. Put this code in the Main MDI Forms TMultLang component OnTranslate event: procedure TForm1.MultLang1Translate(Sender: TObject; LanguageName: string); begin if Form2<>nil then Form2.MultLang1.Translate(LanguageName, False); if Form3<>nil then Form3.MultLang1.Translate(LanguageName, False); .... {continue with each MDI child window} end; Q. The Drop Down list for Forms in the Language Editor is always disabled (grayed out), why ? A. You can only edit other forms in the Language Editor if you are using an external binary file (*.LAN). Make sure you enter a filename (a *.LAN file) in the LanguageFile property of the TMultLang component (the same file for all forms). Q. I can only Browse properties for the form with the cloud in the Language Editor, am I doing something wrong ? A. No, it is the limited functions of the TMultLang package. You can only browse properties on the form you called the Language Editor from (the one with the cloud). You should define which properties you need to translate once at design-time from the Langauge Editor from each form. These can later be translated from any other form if you are using an external file (*.lan). Q. How do I change the User defined string variables for the Design Language since I cannot click on the 'Browse' button from the Language Editor when the design language is selected. A. When you add User defined strings in any other language than the design language, you will automatically get User Defined strings properties inserted in the MultLang component of the design language. Just select the design time language in the Language Editor, you can then select the MultLang component from the Property translation list which then contains newly added user defined strings from other languages. Q. I am using Delphi 2 and I have problems getting the TMultLang component translate the TTabbedNotebook pages. Everything else is translated but the Pages, is this a bug ? A. The TTabbedNotebook is only included for compability reasons in 32 bit Delphi, use the TPageControl instead. The TTabbedNotebook component do have problems setting the Page Caption strings and can therefore cause Memory Access violations. We have turned off the translation of this control under Delphi 2 since you should use the TPageControl instead. Q. I would like to translate the TDBNavigator's Hints of the buttons, but I cannot since I dont see the string list (Hints) in the Browse dialog ? A. Yes, they can be translated, however you must first add the original language strings in the Object Inspector (Hints property). You can then choose them in the Browse dialog of the Language Editor. Q. The TDBNavigators Hints does not change language, but other controls do, during run-time. I need to use the Hints of the TDBNavigator, is there any workaround for this problem. A. Yes, the hints in that control is stored in an internal list. This list is not automatically updated unless the private InitHints method is called of the TDBNavigator. This can be done by including this code in the OnTranslated event of the TMultLang component. var NewHints: TStringList; begin NewHints := TStringList.Create; try NewHints.Assign(DBNavigator1.Hints); DBNavigator1.Hints:=NewHints; {Will make a call to the private InitHints mehtod} finally NewHints.Free; end; end; Q. How can I use the TMultLang component with database reports in ReportSmith ? A. The TMultLang component cannot translate the labels in your report since it is another application. However, you can translate the ReportName property of the TReport component. In this way you can create one reportfile for each language. Q. What about the BDE error messages, can the TMultLang translate those ? A. In the reality no, but there are workarounds. You can use Exception programming to catch the error messages and display them yourself. These error messages can be retrieved from the TMultLang component depending on the selected language. Here's an example try Table1.Active := True; { See if it will open } except on EDatabaseError do begin { Ask if it is OK to retry } MButtons1.Translate:=True; if MessageDlg(MultLang1.GetString('EOpenError'), mtError, [mbOK, mbCancel], 0) <> mrOK then raise; { If not, reraise to abort } MButtons1.Translate:=False; end; end; You can also go beyond this and inherit the TDBError object to include database error messages support. Another solution is to translate all the BDE error strings in the OnTranslated event of the TMultLang component. This can be done by iterating all the strings in the EDBEngineError object, then change each string with the GetString method of the TMultLang component. To change the string in the TDBError object you must first destroy it then create it with the new message taken from the TMultLang component. Q. How can I set the DefaultLanguage from an INI file, without recompiling the Delphi application ? A. Place this code in the OnCreate event of the very first form shown in your project, it is usually the MainForm: procedure TMainForm.FormCreate(Sender: TObject); var AStr:array[0..255] of Char; begin GetPrivateProfileString('Default', 'Language', 'English', AStr, 255, MULTLANGINI); MultLang1.Translate(StrPas(AStr), True); end; Q. I'm using InfoPower's database controls, and I can't translate the column headers, isn't it supported ? A. Yes, you can translate the Columns layout in the wwDBGrid control. There are two methods. If you can access the TField's components from the database the wwDBGrid are using, you can translate the DisplayLabel property of those components. However, if they dont exist (like in Delphi 2.0), you will need to select the Selected 0, Selected 1 ... properties in the Browse dialog of the wwDBGrid component. The translated text should be the third field in the Language Editor (also the second field which adjust the width of the column). Since the wwDBGrid component doesn't understand the run-time change that will occur when switching Language you'll need to insert this code in the OnTranslated event of the TMultLang control: wwDBGrid1.redrawGrid; It is an undocumented method of the wwDBGrid component and will make the grid redraw at run-time. If you're using a calculated field and needs to translate the title, you should also include this code in the OnTranslated event: wwDataSetUpdateFieldProperties(wwDBGrid1.DataSource.Dataset, wwDBGridItem.Selected); Q. I would like to use one textfile for translations of all forms, how can I do that ? A. Version 1.2 or later allows you to use one textfile for all forms, you'll need to export each form in the Language Editor using the 'Save To' button to the same textfile for all forms. Q. I will get translations from several different translators, how can I merge theese translations into my forms alltogether ? A. The translator should give you translated files in the textformat, however if you received it in the .LAN format, you will need to export the translations to a textfile using the Language Editor. Once you have the textfiles, just edit the textfiles and remove all sections that the translator didn't translate Ex: [TMainForm1MultLang1.English] MainForm1.Caption=Gem's [TMainForm1MultLang1.Swedish] MainForm1.Caption=Ädelstenar If the above file comes from a translator who translated this file into Swedish, just remove all items in the [TMainForm1MultLang1.English] section (if it contained more languages, delete those sections too). You will then need to import all the prepared textfiles into your real application. Q. I have a MDI application and when I dynamically create a new Window like Form1 := TForm1.Create(Self); Form1.Show; it will show OK. However when I translate from my Main Window all the dynamically created windows will not switch language unless I close and create the Window again ! A. MultLang post window messages to each Child window to switch language. The dynamically created form is not in the form list of the application and will therefor not receive the message. Instead of using Create constructor to create the form, use the CreateForm method which updates the formlist correctly using this code instead: Application.CreateForm(TForm1, Form1); Form1.Show;